# -*- coding: utf-8 -*-
import util.opends
import crypter
import traceback
from util.logger import process_log
import tools
import ERROR
import datetime
__author__ = 'kongchao'

TASK_TABLE = "task"
DATA_INTERVAL_TIME = 10
ERROR_INTERVAL_TIME = 5
DATE_FORMAT = '%Y-%m-%d %H:%i:%S'
DEFAULT_ERROR_MSG = '监控服务异常，请稍后'
# 线上改为false
DEBUG = False
SQL_TASK_ID = 4202



class SyncException(Exception):
    def __init__(self, status, msg, ds_id=None):
        self.status = status
        self.message = msg
        self.ds_id = ds_id


class SyncBaidu(object):
    def __init__(self):
        self.crypter = crypter.DataCrypter(KEY1='WoBig6Liu0HaiZhi', KEY2='PingNiuBi008')
        self.mysql_tool = tools.MysqlTool()

    def get_sync_sql(self):
        pass

    def sync_data(self, sync_infos):
        pass

    def get_error_sql(self):
        pass

    def sync_error(self, errors):
        pass


class SyncData(SyncBaidu):

    def __init__(self):
        self.crypter = crypter.DataCrypter(KEY1='WoBig6Liu0HaiZhi', KEY2='PingNiuBi008')
        self.mysql_tool = tools.MysqlTool()

    def sync_data_call(self):
        # token = self.crypter.decrypt_data('f3RubB0uOA0AExZ2M3d5CQUMBQQVDAdbfnAJOyQEADYnMRQCfmd9axIlMGeKAAAA')
        # opends = util.opends.OpenDS(token)
        # opends.ds_status(token, 'ds_c788c08eaed74629b8c9ca36248b2c92', status=4)
        # return
        try:
            sync_infos = self.mysql_tool.fetch_all_dict(self.get_sync_sql())
        except Exception, e:
            process_log().info(traceback.format_exc())
            self.mysql_tool.close_connect()
            raise SyncException(ERROR.FAIL, u"获取同步信息失败%s" % e)
        if not sync_infos:
            process_log().warning(u"本次未检测到需要同步的数据")
            return
        try:
            self.sync_data(sync_infos)
        except Exception, e:
            process_log().error(traceback.format_exc())
            raise SyncException(ERROR.FAIL, u"数据同步失败,%s" % e)
        finally:
            self.mysql_tool.close_connect()

    def get_sync_sql(self):
        # sql = "select * from %s " \
        #       "where datetime>DATE_FORMAT(now(),'%%Y-%%m-%%d %%H:00:00') " \
        #       "and now()>=DATE_ADD(datetime,INTERVAL %d MINUTE) and status<>'fail'" % (TASK_TABLE, DATA_INTERVAL_TIME,)
        sql = "select * from %s " \
              "where datetime>=DATE_FORMAT(now(),'%%Y-%%m-%%d %%H:00:00') " \
              "and datetime<=DATE_FORMAT(now(),'%%Y-%%m-%%d %%H:%%i:%%s')and status<>'fail'" % (TASK_TABLE,)
        process_log().info(sql)
        if DEBUG:
            sql = "select * from %s where id> %d" % (TASK_TABLE, SQL_TASK_ID)
            process_log().debug(sql)
        return sql

    def get_data(self, sync_info):
        token = self.crypter.decrypt_data(sync_info['token'])
        fields = ",".join(self.get_fields(token, sync_info['tb_id'],format=True))
        sql = "select %s from %s where task_id='%s'" % (fields, sync_info['tb_id'], sync_info['task_id'])
        data = self.mysql_tool.fetch_all_list(sql)
        return data

    def get_fields(self, token, tb_id, format=False):
        opends = util.opends.OpenDS(token)
        result = opends.field_list(token, tb_id=tb_id)
        #result = opends.tb_info(token, tb_id=tb_id)
        #fields = result['fields']
        #print(result)
        field_list = []
        for field in result:
            field_name = field['name']
            if format:
                if field['name'] == 'datetime':
                    field_name = "DATE_FORMAT(%s,'%s')" % (field['name'], DATE_FORMAT)
                if field['name'] in ('desc', 'link'):
                    field_name = "`%s`" % (field['name'])
            # if field['name'] == 'link':
            #     continue
            field_list.append(field_name)
        return field_list

    def sync_data(self, sync_infos):
        task_start = datetime.datetime.now()
        # update_tbs = []
        for sync_info in sync_infos:
            start_time = datetime.datetime.now()
            try:
                token = self.crypter.decrypt_data(sync_info['token'])
            except Exception, e:
                process_log().error(u"token验证失败,%s" % e)
            try:
                opends = util.opends.OpenDS(token)
                data = self.get_data(sync_info)
                fields = self.get_fields(token, sync_info['tb_id'])
                # opends.tb_clean(token, sync_info['tb_id'])
                opends.data_insert(token, sync_info['tb_id'], fields, data)
                opends.tb_commit(token, sync_info['tb_id'])
                opends.ds_status(token, sync_info['ds_id'], status=ERROR.SUCCESS, error_msg='')
                # update_tbs.append(sync_info['tb_id'])
                try:
                    opends.tb_update(token, [sync_info['tb_id']])
                except Exception, e:
                    process_log().error(u"update失败,%s" % traceback.format_exc())
                end_time = datetime.datetime.now()
                process_log().info("start_time:[%s]\tend_time:[%s]\t task[%s]\t cost total time:[%sS]" %
                                   (start_time, end_time, sync_info['task_id'], (end_time-start_time).seconds))
            except Exception, e:
                try:
                    process_log().error(traceback.format_exc())
                    opends.ds_status(token, sync_info['ds_id'], status=ERROR.FAIL, error_msg=DEFAULT_ERROR_MSG)
                except Exception, e:
                    process_log().error(traceback.format_exc())
                    process_log().error(u"调用ds_status接口失败,%s" % e)
        task_end = datetime.datetime.now()
        process_log().info("task_start:[%s]\t task_end:[%s]\t cost_time:[%sS]" %
                           (task_start, task_end, (task_end-task_start).seconds))


class SyncError(SyncBaidu):

    def __init__(self):
        self.crypter = crypter.DataCrypter(KEY1='WoBig6Liu0HaiZhi', KEY2='PingNiuBi008')
        self.mysql_tool = tools.MysqlTool()

    def sync_error_call(self):
        try:
            errors = self.mysql_tool.fetch_all_dict(self.get_error_sql())
        except Exception, e:
            process_log().info(traceback.format_exc())
            raise SyncException(ERROR.FAIL, u"获取error信息失败%s" % e)
        if not errors:
            process_log().warning(u"本次任务没有需要报告的错误信息")
            return
        try:
            self.sync_error(errors)
        except Exception, e:
            process_log().error(traceback.format_exc())
            raise SyncException(ERROR.FAIL, u"同步error信息失败")
        finally:
            self.mysql_tool.close_connect()

    def get_error_sql(self):
        sql = "select * from %s where status='fail' " \
              "and now()<=DATE_ADD(datetime,INTERVAL %d MINUTE)" % (TASK_TABLE, ERROR_INTERVAL_TIME)
        if DEBUG:
            sql = "select * from %s where status='fail' " % (TASK_TABLE,)
        return sql

    def sync_error(self, errors):
        for error in errors:
            try:
                token = self.crypter.decrypt_data(error['token'])
                opends = util.opends.OpenDS(token)
                opends.ds_status(token, error['ds_id'], status=ERROR.FAIL, error_msg=error['error_msg'])
            except Exception, e:
                process_log().error(u"调用ds_status接口失败")
                process_log().error(traceback.format_exc())
                continue
